package com.wei.czz.framework.admin.controller;

import java.io.IOException;
import java.util.*;

import com.alibaba.excel.EasyExcel;
import com.wei.czz.common.annotation.Auth;
import com.wei.czz.common.annotation.Resubmit;
import com.wei.czz.common.dto.admin.menu.MenuPageEnumDto;
import com.wei.czz.common.dto.admin.menu.MenuViewDto;
import com.wei.czz.common.dto.admin.menu.UserMenuDto;
import com.wei.czz.common.dto.common.UploadDto;
import com.wei.czz.common.easyexcel.listener.ObjectUploadListener;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.dto.admin.menu.MenuDto;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.enums.admin.menu.MenuDisplayEnum;
import com.wei.czz.common.enums.admin.menu.MenuTypeEnum;
import com.wei.czz.common.jsr303.group.OrderSearch;
import com.wei.czz.common.jsr303.group.Save;
import com.wei.czz.common.jsr303.group.Search;
import com.wei.czz.common.jsr303.group.Update;
import com.wei.czz.common.property.BatchProperty;
import com.wei.czz.common.tool.PageDto;
import com.wei.czz.common.tool.Result;
import com.wei.czz.common.utils.ExcelUtils;
import com.wei.czz.common.vo.admin.menu.MenuUploadVo;
import com.wei.czz.common.vo.common.UpdateStatusVo;
import com.wei.czz.common.vo.admin.menu.MenuFormVo;
import com.wei.czz.common.vo.admin.menu.MenuVo;
import com.wei.czz.framework.admin.manager.MenuManager;
import com.wei.czz.framework.admin.service.MenuService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wei
 * date: 2021-03-15 10:30:18
 * className: MenuController 系统菜单操作请求接口类
 * version: 1.1
 * description:
 */
@RestController
@RequestMapping("/sys/menu")
@AllArgsConstructor
public class MenuController {

    private static final Logger log = LoggerFactory.getLogger(MenuController.class);

    private final BatchProperty batchProperty;

    private final MenuService menuService;

    private final MenuManager menuManager;

    /**
     * 保存菜单数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页面-菜单操作弹出框调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuVo 菜单参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "保存菜单信息")
    @PostMapping("/save")
    @Auth(permit = "system:menu:save")
    public Result<Object> save(@Validated(Save.class) @RequestBody MenuVo menuVo) {
        log.info("开始保存菜单数据业务。{}", menuVo);
        if (MenuTypeEnum.isFail(menuVo.getType())) {
            log.info("保存菜单数据接口，菜单类型参数错误");
            return Result.paramFail();
        }
        if (MenuDisplayEnum.isFail(menuVo.getDisplay())) {
            log.info("保存菜单数据接口，菜单显示状态参数错误");
            return Result.paramFail();
        }
        if (menuVo.getType().equals(MenuTypeEnum.PACKAGE_TYPE.getValue())) {
            if (StringUtils.isNoneBlank(menuVo.getPath(), menuVo.getPermit()) || StringUtils.isBlank(menuVo.getIcon())) {
                log.info("系统菜单添加接口，目录菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘目录’时，菜单图标字段必填，菜单路径和权限标识字段都不用填！");
            }
        }
        if (menuVo.getType().equals(MenuTypeEnum.PAGE_TYPE.getValue())) {
            if (StringUtils.isAnyBlank(menuVo.getPath(), menuVo.getIcon()) || StringUtils.isNotBlank(menuVo.getPermit())) {
                log.info("系统菜单添加接口，路由菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘菜单’时，菜单路径和菜单图标字段字段必填，权限标识字段不用填！");
            }
        }
        if (menuVo.getType().equals(MenuTypeEnum.BUTTON_TYPE.getValue())) {
            if (StringUtils.isNoneBlank(menuVo.getPath(), menuVo.getIcon()) || StringUtils.isBlank(menuVo.getPermit())) {
                log.info("系统菜单添加接口，按钮菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘按钮’时，权限标识字段必填，菜单路径和菜单图标字段不用填！");
            }
        }

        menuManager.saveMenu(menuVo);

        log.info("保存菜单数据业务结束");
        return Result.success();
    }

    /**
     * 批量保存菜单数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页-批量保存菜单弹出框中调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuVoList 菜单参数对象列表
     * @return 不返回数据
     */
    @Resubmit(message = "批量保存菜单")
    @PostMapping("/batch/save")
    @Auth(permit = "system:menu:save")
    public Result<Object> batchSaveMenu(@RequestBody List<MenuVo> menuVoList) {
        log.info("开始批量保存菜单数据业务。{}", menuVoList);
        if (menuVoList.isEmpty()) {
            return Result.clientFail("菜单列表不能为空");
        }
        if (menuVoList.size() > 20) {
            log.info("批量添加菜单，数量超过20条。size={}", menuVoList.size());
            return Result.clientFail("一次批量添加菜单，数量不能超过20条");
        }
        for (MenuVo menuVo : menuVoList) {
            if (menuVo.isBatchSaveParamsFail()) {
                log.info("批量保存菜单数据接口，菜单参数数据有误。{}", menuVo);
                return Result.clientFail("传入菜单数据有误，请确认。");
            }
        }

        menuManager.batchSaveMenu(menuVoList);

        log.info("批量保存菜单数据业务结束");
        return Result.success();
    }

    /**
     * 上传菜单接口
     * <p>
     * 调用方：
     *  1、浏览器-后台-菜单管理页面-上传抽屉中调用
     * <p>
     * 此接口会校验是否重复提交
     * @param file 文件对象
     * @return 结果
     */
    @Resubmit(spEL = "'uploadMenu' + #userId", message = "上传菜单")
    @PostMapping("/upload")
    @Auth(permit = "system:menu:save")
    public Result<UploadDto<MenuUploadVo>> uploadMenu(@RequestParam MultipartFile file,
                                                      @RequestParam("mustAll") Boolean mustAll) {
        log.info("开始上传菜单业务。mustAll={} fileName={} fileSize={}", mustAll, file.getOriginalFilename(), file.getSize());

        ObjectUploadListener<MenuUploadVo> objectUploadListener = new ObjectUploadListener<>();
        try {
            // 解析数据
            EasyExcel.read(file.getInputStream(), MenuUploadVo.class, objectUploadListener).sheet().doRead();

        } catch (IOException e) {
            log.error("菜单上传文件解析异常。message={}", e.getMessage(), e);
            return Result.fail();
        }

        if (objectUploadListener.isEmpty()) {
            log.info("菜单导入文件内容为空");
            return Result.clientFail("菜单导入文件内容不能为空");
        }
        if (batchProperty.getMaxSize() < objectUploadListener.getTotal()) {
            log.warn("菜单导入数量超限。batch.maxSize={} list.size={}", batchProperty.getMaxSize(),
                    objectUploadListener.getTotal());
            return Result.clientFail("一次导入菜单操作最多允许同时导入" + batchProperty.getMaxSize() + "个菜单");
        }

        UploadDto<MenuUploadVo> uploadDto = menuManager.uploadMenu(mustAll, objectUploadListener);

        log.info("上传部门业务结束");
        return Result.success(uploadDto);
    }

    /**
     * 缓存菜单数据接口
     * 根据菜单id列表，将对应的所有菜单信息写入缓存中
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuIdList 菜单id列表
     * @return 请求结果
     */
    @Resubmit(message = "缓存菜单")
    @PostMapping("/cache")
    @Auth(permit = "cache:menu:opt")
    public Result<Object> cacheMenu(@RequestBody List<Long> menuIdList) {
        log.info("开始缓存菜单信息业务。menuIdList={}", menuIdList);

        if (menuIdList.isEmpty()) {
            log.info("缓存菜单信息接口，请求参数错误");
            return Result.paramFail();
        }

        menuService.cacheMenu(menuIdList);

        log.info("缓存菜单信息业务结束");
        return Result.success();
    }

    /**
     * 缓存全部菜单信息接口
     * 将系统所有菜单信息写入缓存中
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     * <p>
     * 此接口会校验是否重复提交
     * @return 请求结果
     */
    @Resubmit(message = "缓存全部菜单")
    @GetMapping("/cache/all")
    @Auth(permit = "cache:menu:opt")
    public Result<Object> cacheAllMenu() {
        log.info("开始缓存全部菜单信息业务");

        menuService.cacheAllMenu();

        log.info("缓存全部菜单信息业务结束");
        return Result.success();
    }

    /**
     * 分页获取菜单接口
     * 分页查询一级菜单数据（每个一级菜单下包含自己的二级菜单、二级菜单又包含自己的三级菜单，以此类推）
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页中调用
     * @param menuVo 菜单查询参数对象
     * @return 分页查询结果
     */
    @PostMapping("/page/list")
    @Auth(permit = "system:menu:list")
    public Result<PageDto<MenuDto>> getPageMenuList(@Validated(Search.class) @RequestBody MenuFormVo menuVo) {
        log.info("开始分页查询菜单数据列表业务。{}", menuVo);

        PageDto<MenuDto> page = menuManager.getPageMenuList(menuVo);

        log.info("分页查询菜单列表业务结束");
        return Result.success(page);
    }

    /**
     * 获取菜单管理页面枚举接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页中调用
     * @return 结果
     */
    @GetMapping("/page/param")
    @Auth(permit = "system:menu:list")
    public Result<MenuPageEnumDto> getMenuPageParam() {
        log.info("开始获取菜单管理页面枚举业务");

        MenuPageEnumDto menuPageEnumDto = menuManager.getMenuPageParam();

        log.info("获取菜单管理页面枚举业务结束");
        return Result.success(menuPageEnumDto);
    }

    /**
     * 分页查询菜单缓存列表接口
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     * @param menuFormVo 菜单缓存查询参数对象
     * @return 请求结果
     */
    @PostMapping("/cache/list")
    @Auth(permit = "cache:menu:list")
    public Result<Map<String, Object>> getCacheMenuList(
            @Validated(OrderSearch.class) @RequestBody MenuFormVo menuFormVo) {
        log.info("开始分页查询菜单缓存列表业务。{}", menuFormVo);

        Map<String, Object> result = menuService.getCacheMenuList(menuFormVo);

        log.info("分页查询菜单缓存列表业务结束");
        return Result.success(result);
    }

    /**
     * 获取菜单树接口
     * 1、获取所有菜单类型为“目录”或“菜单”的菜单数据，并构造成树形结构
     * 2、如果菜单主键和参数menuId一致，则不将该菜单加入菜单树中，同理其子菜单也不加入。
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页面-菜单操作弹出框调用
     *  2、浏览器-后台管理页面-菜单管理页面-批量添加菜单弹出框调用
     * @param menuId 菜单主键
     * @return 菜单树数据
     */
    @GetMapping("/tree")
    @Auth(permit = { "system:menu:save", "system:menu:update" })
    public Result<MenuDto> getMenuTree(@RequestParam(value = "menuId", required = false) Long menuId) {
        log.info("开始获取菜单树业务。menuId={}", menuId);

        MenuDto menu = menuService.getMenuTree(menuId);

        log.info("获取菜单树业务结束");
        return Result.success(menu);
    }

    /**
     * 获取用户关联菜单树接口
     * 根据用户信息，获取用户关联菜单数据，并构造成菜单树
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-侧边菜单组件调用
     */
    @GetMapping("/user/menu")
    @Auth(permit = "user:info:get")
    public Result<UserMenuDto> getUserMenu() {
        log.info("开始获取用户关联菜单树业务");

        UserMenuDto userMenuDto = menuManager.getUserMenu();

        log.info("获取用户关联菜单树业务结束");
        return Result.success(userMenuDto);
    }

    /**
     * 获取菜单缓存信息接口
     * 根据菜单id，获取菜单缓存信息
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     *
     * @param menuVo 菜单请求参数对象
     * @return 请求结果
     */
    @PostMapping("/cache/info")
    @Auth(permit = "cache:menu:info")
    public Result<Map<String, Object>> getMenuOnCache(@RequestBody MenuVo menuVo) {
        log.info("开始获取菜单缓存信息业务。{}", menuVo);

        if (Objects.isNull(menuVo.getMenuId())) {
            log.info("获取菜单缓存信息接口请求参数错误");
            return Result.paramFail();
        }

        Map<String, Object> result = menuService.getMenuOnCache(menuVo);

        log.info("获取菜单缓存信息业务结束");
        return Result.success(result);
    }

    /**
     * 获取子菜单下一个默认排序等级接口
     * 根据菜单主键，获取该菜单下子菜单的下一个默认排序等级数值
     * @param menuId 菜单主键
     * @return 下一个默认排序等级数值
     */
    @GetMapping("/next/sort")
    @Auth(permit = "system:menu:save")
    public Result<Integer> getNextSort(@RequestParam(value = "menuId", required = false) Long menuId) {
        log.info("开始获取菜单下一个默认排序等级业务。menuId={}", menuId);
        if (Objects.isNull(menuId)) {
            menuId = CommonEnum.ZERO.getLongValue();
        }

        Integer nextSort = menuService.getNextSort(menuId);

        log.info("获取菜单下一个默认排序等级业务结束");
        return Result.success(nextSort);
    }

    /**
     * 获取菜单展示数据接口
     * @param menuId 菜单主键
     * @return 菜单展示数据
     */
    @GetMapping("/view")
    @Auth(permit = "system:menu:info")
    public Result<MenuViewDto> getMenuViewData(@RequestParam("menuId") Long menuId) {
        log.info("开始获取菜单展示数据业务。menuId={}", menuId);

        MenuViewDto menuViewDto = menuManager.getMenuViewData(menuId);

        log.info("获取菜单展示数据业务结束");
        return Result.success(menuViewDto);
    }

    /**
     * 下载菜单导入模板接口
     * <p>
     * 调用方：
     *  1、浏览器-后台-菜单管理页面-上传抽屉中调用
     * @param response 响应对象
     * @return 结果
     */
    @GetMapping("/download/upload-template")
    @Auth(permit = "system:menu:save")
    public Result<Object> downloadUploadTemplate(HttpServletResponse response) {
        log.info("开始下载菜单导入模板业务");

        List<MenuUploadVo> list = new ArrayList<>(4);

        MenuUploadVo menuUploadVo = new MenuUploadVo();
        menuUploadVo.setSerial(1);
        menuUploadVo.setParentNo(CommonEnum.ZERO.getLongValue());
        menuUploadVo.setName("第一层级菜单，父级菜单主键为0");
        menuUploadVo.setTypeName(MenuTypeEnum.PACKAGE_TYPE.getName());
        menuUploadVo.setPath(StringUtils.EMPTY);
        menuUploadVo.setPermit(StringUtils.EMPTY);
        menuUploadVo.setIcon("");
        menuUploadVo.setSort(1);
        menuUploadVo.setDisplayName(MenuDisplayEnum.DISPLAY_SHOW.getName());
        list.add(menuUploadVo);

        menuUploadVo = new MenuUploadVo();
        menuUploadVo.setSerial(2);
        menuUploadVo.setParentNo(null);
        menuUploadVo.setName("测试菜单");
        menuUploadVo.setTypeName(MenuTypeEnum.PAGE_TYPE.getName());
        menuUploadVo.setPath("/admin/top-menu");
        menuUploadVo.setPermit(StringUtils.EMPTY);
        menuUploadVo.setIcon("");
        menuUploadVo.setSort(1);
        menuUploadVo.setDisplayName(MenuDisplayEnum.DISPLAY_SHOW.getName());
        list.add(menuUploadVo);

        menuUploadVo = new MenuUploadVo();
        menuUploadVo.setSerial(3);
        menuUploadVo.setParentNo(2L);
        menuUploadVo.setName("测试菜单下的权限菜单1");
        menuUploadVo.setTypeName(MenuTypeEnum.BUTTON_TYPE.getName());
        menuUploadVo.setPath(StringUtils.EMPTY);
        menuUploadVo.setPermit("test:test");
        menuUploadVo.setIcon(StringUtils.EMPTY);
        menuUploadVo.setSort(1);
        menuUploadVo.setDisplayName(MenuDisplayEnum.DISPLAY_SHOW.getName());
        list.add(menuUploadVo);

        menuUploadVo = new MenuUploadVo();
        menuUploadVo.setSerial(4);
        menuUploadVo.setParentNo(2L);
        menuUploadVo.setName("测试菜单下的权限菜单2");
        menuUploadVo.setTypeName(MenuTypeEnum.BUTTON_TYPE.getName());
        menuUploadVo.setPath(StringUtils.EMPTY);
        menuUploadVo.setPermit("test2:test2");
        menuUploadVo.setIcon(StringUtils.EMPTY);
        menuUploadVo.setSort(2);
        menuUploadVo.setDisplayName(MenuDisplayEnum.DISPLAY_SHOW.getName());
        list.add(menuUploadVo);

        ExcelUtils.writeResponse("菜单导入模板", list, menuUploadVo.getTemplatePropertyList(),
                MenuUploadVo.class, response);

        log.info("下载菜单导入模板业务结束");
        return null;
    }

    /**
     * 菜单自选数据导出接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页中调用
     * @param taskId 导出任务主键
     * @return 结果
     */
    @GetMapping("/choice-export")
    @Auth(permit = "system:menu:save")
    public Result<Object> menuChoiceExport(@RequestParam("taskId") Long taskId, HttpServletResponse response) {
        log.info("开始菜单选择导出业务。taskId={}", taskId);

        menuManager.menuChoiceExport(taskId, response);

        log.info("菜单选择导出业务结束");
        return null;
    }

    /**
     * 修改菜单数据接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页面-菜单操作弹出框调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuVo 菜单参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "修改菜单信息")
    @PostMapping("/update")
    @Auth(permit = "system:menu:update")
    public Result<Object> update(@Validated(Update.class) @RequestBody MenuVo menuVo){
        log.info("开始系统菜单信息修改业务。{}", menuVo);
        if (MenuTypeEnum.isFail(menuVo.getType())) {
            log.info("修改菜单数据接口，菜单类型参数错误");
            return Result.paramFail();
        }
        if (MenuDisplayEnum.isFail(menuVo.getDisplay())) {
            log.info("修改菜单数据接口，菜单显示状态参数错误");
            return Result.paramFail();
        }
        if (menuVo.getType().equals(MenuTypeEnum.PACKAGE_TYPE.getValue())) {
            if (StringUtils.isNoneBlank(menuVo.getPath(), menuVo.getPermit()) || StringUtils.isBlank(menuVo.getIcon())) {
                log.info("修改菜单数据接口，目录菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘目录’时，菜单图标字段必填，菜单路径和权限标识字段都不用填！");
            }
        }
        if (menuVo.getType().equals(MenuTypeEnum.PAGE_TYPE.getValue())) {
            if (StringUtils.isAnyBlank(menuVo.getPath(), menuVo.getIcon()) || StringUtils.isNotBlank(menuVo.getPermit())) {
                log.info("修改菜单数据接口，路由菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘菜单’时，菜单路径和菜单图标字段字段必填，权限标识字段不用填！");
            }
        }
        if (menuVo.getType().equals(MenuTypeEnum.BUTTON_TYPE.getValue())) {
            if (StringUtils.isNoneBlank(menuVo.getPath(), menuVo.getIcon()) || StringUtils.isBlank(menuVo.getPermit())) {
                log.info("修改菜单数据接口，按钮菜单参数错误");
                return Result.getResult(ResultEnum.REQUEST_FAIL.getCode(),
                        "菜单类型为‘按钮’时，权限标识字段必填，菜单路径和菜单图标字段不用填！");
            }
        }

        menuManager.updateMenu(menuVo);

        log.info("系统菜单信息修改业务结束");
        return Result.success();
    }

    /**
     * 修改菜单状态接口
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页面-菜单操作弹出框调用
     * <p>
     * 此接口会校验是否重复提交
     * @param updateStatusVo 菜单参数对象
     * @return 不返回数据
     */
    @Resubmit(message = "修改菜单状态")
    @PostMapping("/update/status")
    @Auth(permit = "system:menu:update")
    public Result<Object> updateMenuStatus(@Validated @RequestBody UpdateStatusVo updateStatusVo) {
        log.info("开始修改菜单状态业务。{}", updateStatusVo);

        menuManager.updateMenuStatus(updateStatusVo);

        log.info("修改菜单状态业务结束");
        return Result.success();
    }

    /**
     * 删除菜单数据接口
     * 根据菜单主键，删除菜单数据 及 删除菜单关联的角色数据
     * <p>
     * 调用方：
     *  1、浏览器-后台管理页面-菜单管理页面调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuId 菜单主键
     */
    @Resubmit(message = "删除菜单")
    @DeleteMapping("/delete")
    @Auth(permit = "system:menu:delete")
    public Result<Object> delete(@RequestParam("menuId") Long menuId){
        log.info("开始根据菜单id删除菜单信息业务。{}", menuId);

        menuManager.deleteMenu(menuId);

        log.info("根据菜单id删除菜单信息业务结束");
        return Result.success();
    }

    /**
     * 删除菜单缓存接口
     * 根据菜单id列表，批量删除菜单缓存信息
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     * <p>
     * 此接口会校验是否重复提交
     * @param menuIdList 菜单id列表
     * @return 请求结果
     */
    @Resubmit(message = "删除菜单缓存")
    @DeleteMapping("/cache/delete")
    @Auth(permit = "cache:menu:delete")
    public Result<Object> deleteMenuOnCache(@RequestBody List<String> menuIdList) {
        log.info("开始删除菜单缓存业务。menuIdList={}", menuIdList);

        if (menuIdList.isEmpty()) {
            log.info("删除菜单缓存接口，请求参数错误");
            return Result.paramFail();
        }
        String[] newMenuIds = new String[menuIdList.size()];
        // 所有菜单id字段解密
        for (int i = 0; i < menuIdList.size(); i++) {
            newMenuIds[i] = menuIdList.get(i);
        }

        menuService.deleteMenuOnCache(newMenuIds);

        log.info("删除菜单缓存业务结束");
        return Result.success();
    }

    /**
     * 清空菜单缓存信息接口
     * 清空菜单缓存信息
     * <p>
     * 调用方
     *  1、浏览器-后台管理页-菜单缓存管理页调用
     * <p>
     * 此接口会校验是否重复提交
     * @return 请求结果
     */
    @Resubmit(message = "清空菜单缓存")
    @DeleteMapping("/cache/clear")
    @Auth(permit = "cache:menu:delete")
    public Result<Object> clearMenuOnCache() {
        log.info("开始清空菜单缓存信息业务");

        menuService.clearMenuOnCache();

        log.info("清空菜单缓存信息业务结束");
        return Result.success();
    }

}
